﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSC.Portal.Entities;
using System.Reflection;
using JSC.Portal.Module.Models;
using System.Web.Mvc;

namespace JSC.Portal.Module
{
    public abstract class ModuleBase : IModuleBase
    {
        protected ModuleBase(Section section)
        {
            Section = section;
        }

        private void Initialize()
        {
            Data = new ModuleViewData(Section, DesignMode, this);
            Placeholder = Section.Placeholder;
            ControllerName = Section.ModuleType.ControllerName;
            ViewName = Section.ModuleType.ViewName;
            ReadSectionSettings();
        }

        public static ModuleBase GetModuleFromSection(Section section, bool desingMode)
        {
            string fullyQualifiedTypeName = string.Format("{0}, {1}",
                section.ModuleType.ClassName, section.ModuleType.AssemblyName);
            Type typeToInstanciate = Type.GetType(fullyQualifiedTypeName);
            ConstructorInfo ci = typeToInstanciate.GetConstructor(new Type[1] { typeof(Section) });
            ModuleBase result = (ModuleBase)ci.Invoke(new object[1] { section });
            result.DesignMode = desingMode;
            result.Initialize();

            return result;
        }

        public static ModuleBase GetModuleFromSection(Section s)
        {
            return GetModuleFromSection(s, false);
        }

        public ModuleViewData Data
        {
            get;
            private set;
        }

        public String Placeholder
        {
            get;
            private set;
        }

        public Section Section
        {
            get;
            private set;
        }

        public bool Syndicatable
        {
            get;
            protected set;
        }

        public string ControllerName
        {
            get;
            set;
        }

        public string ViewName
        {
            get;
            set;
        }

        public bool DesignMode
        {
            get;
            private set;
        }

        /// <summary>
        /// Configure the module by reading the settings of the section.
        /// </summary>
        protected virtual void ReadSectionSettings()
        {
            if (Section == null)
            {
                throw new NullReferenceException("Can't access the section for settings.");
            }
        }

        /// <summary>
        /// Check if the module contains no invalid settings. Override this method in concrete module controllers.
        /// </summary>
        protected virtual void ValidateSectionSettings()
        {
            // Do nothing here
            return;
        }

        public virtual void Load()
        {

        }

        public virtual void LoadById(int id)
        {

        }

        public virtual void LoadByIdAndPath(int id, string path)
        {

        }
    }
}
